package procsim;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class RegistersDialog extends JDialog implements ActionListener, KeyListener {
    private JPanel panel = new JPanel(new BorderLayout());
    private JPanel panelEast = new JPanel(new GridBagLayout());
    private JPanel panelWest = new JPanel(new GridLayout(1, 2, 5, 5));
    private JPanel panelWest1 = new JPanel(new GridBagLayout());
    private JPanel panelWest2 = new JPanel(new GridBagLayout());
    private JPanel panelSouth = new JPanel(new FlowLayout());
    private JButton buttonUpdate = new JButton("Update");
    private JButton buttonCancel = new JButton("Cancel");
    private JTextField[] tfA, tfO1, tfO2;
    private MSignal[] registersA, registersO1, registersO2;
    private int[] valuesA;
    private Program parent;
    RegistersDialog(MSignal[] regsO1, MSignal[] regsO2, MSignal[] regsA, Program prog){
        setTitle("Registers");
        registersA = regsA;
        registersO1 = regsO1;
        registersO2 = regsO2;
        valuesA = new int[registersA.length];
        update();
        parent = prog;
        buttonUpdate.addActionListener(this);
        buttonUpdate.addKeyListener(this);
        buttonCancel.addActionListener(this);
        buttonCancel.addKeyListener(this);
        panelSouth.add(buttonUpdate);
        panelSouth.add(buttonCancel);
        if(registersA!=null) tfA=formRegisters(panelEast, tfA, registersA, true);
        if(registersO1!=null) tfO1=formRegisters(panelWest1, tfO1, registersO1, false);
        if(registersO2!=null) tfO2=formRegisters(panelWest2, tfO2, registersO2, false);
        panelWest.add(panelWest1);
        panelWest.add(panelWest2);
        panel.add(panelEast, "East");
        panel.add(panelWest, "West");
        panel.add(panelSouth, "South");
        setContentPane(panel);
        setSize(350, 350);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
    }
    private JTextField[] formRegisters(JPanel panel, JTextField[] tf, MSignal[] regs, boolean editable){
        int len = regs.length, tflen;
        tf = new JTextField[len];
        for(int i=0; i<len; i++){
            if(regs[i].getNumOfBits()==8) tflen=2;
            else tflen=regs[i].getNumOfBits()/4-1;
            tf[i]=new JTextField(String.format("%x", regs[i].get()), tflen);
            tf[i].setEditable(editable);
            tf[i].addKeyListener(this);
            JLabel lab = new JLabel(regs[i].getName()+":", SwingConstants.TRAILING);
            panel.add(lab, new GridBagConstraints(0, i, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
            panel.add(tf[i], new GridBagConstraints(1, i, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
        }
        return tf;
    }
    public void update(){
        for(int i=0; i<registersA.length; i++)
            valuesA[i]=registersA[i].get();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getActionCommand().equals("Update")){
            try{
                for(int i=0; i<registersA.length; i++){
                    int val = Util.hex2Int(tfA[i].getText(), registersA[i].getNumOfBits());
                    registersA[i].set(val);
                    valuesA[i]=val;
                }
                parent.setStatus("Registers updated.");
            } catch(NumberFormatException nfe){
                JOptionPane.showMessageDialog(null, nfe.getLocalizedMessage(), "Input error", JOptionPane.ERROR_MESSAGE);
            }
        }
        else if(e.getActionCommand().equals("Cancel")){
            setVisible(false);
            for(int i=0; i<registersA.length; i++)
                tfA[i].setText(String.format("%x", valuesA[i]));
        }
    }
    @Override
    public void keyTyped(KeyEvent ke) { }
    @Override
    public void keyPressed(KeyEvent ke) {
        if(ke.getKeyCode()==KeyEvent.VK_ESCAPE)
            setVisible(false);
        else if(ke.getKeyCode()==KeyEvent.VK_ENTER && (ke.getComponent() instanceof JButton || ke.getComponent() instanceof JTextField)){
            if(ke.getComponent()==buttonCancel)
                actionPerformed(new ActionEvent(ke.getComponent(), ActionEvent.ACTION_PERFORMED, buttonCancel.getText()));
            else
                actionPerformed(new ActionEvent(ke.getComponent(), ActionEvent.ACTION_PERFORMED, buttonUpdate.getText()));
        }
    }
    @Override
    public void keyReleased(KeyEvent ke) { }
}
